/*pipedemo.c*/
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>

// 定义要发送的字符串
char sendbuf[]="I am Linux";
// 定义子进程接收数据的缓冲区
char recbuf[20];
// 定义父进程接收数据的缓冲区
char parrecbuf[20];

// 反转字符串的函数
void reverse(char *str1) 
{
    // 如果传入的字符串指针为空，直接返回
    if (str1==NULL) return;
    // 定义两个指针，分别指向字符串的开头和结尾
    char* p = str1 ; 
    char* q = str1 ;
    // 移动指针 q 到字符串的末尾
    while( *q )   ++q ;
    // 回退一个位置，指向字符串的最后一个字符
    q -- ;
    // 交换 p 和 q 指向的字符，直到 p 和 q 相遇
    while(q > p)
    {
        char t = *p ;
        *p++ = *q ;
        *q-- = t ;
    }
}

int main() {
    // 定义管道的文件描述符数组，mypipe[0] 用于读，mypipe[1] 用于写
    int mypipe[2],fd;   
    // 创建管道，如果创建失败，输出错误信息并退出程序
    if ( pipe(mypipe)<0 ) { perror("pipe failed"); exit(0);  }
    // 创建子进程，如果创建失败，输出错误信息并退出程序
    if ( (fd=fork())<0 )  { perror("fork failed"); exit(0);  }
    // 子进程执行的代码
    if ( fd==0 ) { 
        // 从管道的读端读取数据，存储到 recbuf 缓冲区中
        read(mypipe[0],recbuf,strlen(sendbuf));
        // 输出子进程接收到的数据
        printf("The child process get %s\n",recbuf);
        // 调用 reverse 函数反转接收到的字符串
        reverse(recbuf);  
        // 将反转后的字符串写入管道的写端
        write(mypipe[1],recbuf,strlen(recbuf));  
    }
    // 父进程执行的代码
    if (fd>0) {
        // 将 sendbuf 中的数据写入管道的写端
        write(mypipe[1],sendbuf,strlen(sendbuf));
        // 父进程休眠 10 秒，等待子进程处理数据
        sleep(10); 
        // 从管道的读端读取子进程处理后的数据，存储到 parrecbuf 缓冲区中
        read(mypipe[0],parrecbuf,strlen(sendbuf));
        // 输出父进程接收到的数据
        printf("The parent process get %s\n",parrecbuf);
        // 等待子进程结束
        wait();
    }
    return 0;
}